import 'dart:convert';
import 'dart:core';
import 'package:dio/dio.dart';
import 'package:flutter_wan_android/generated/json/base/json_convert_content.dart';
import 'dio_singleton.dart';
import 'http_exception.dart';
import 'http_result.dart';

class HttpUtils<T> {
  ///
  /// 统一处理实体对象
  ///
  HttpResult<T> _getHttpResult(Map<String, dynamic> responseData) {
    HttpResult result = HttpResult<T>.parseData(responseData);
    if (result == null) {
      ///解析HttpResult对象错误
      throw AppHttpException(HttpErrorType.dataEmpty, message: "json 解析失败");
    } else if (result.code != HttpResult.HTTP_STATUS_OK) {
      ///返回错误状态
      throw AppHttpException(HttpErrorType.statusError,
          message: result.message);
    }
    return result; // continue
  }

  ///
  /// 统一异常处理
  ///
  AppHttpException _handleException(Exception ex) {
    if (ex is DioError) {
      ///网络超时
      if (ex.type == DioErrorType.CONNECT_TIMEOUT ||
          ex.type == DioErrorType.SEND_TIMEOUT ||
          ex.type == DioErrorType.RECEIVE_TIMEOUT) {
        return AppHttpException(HttpErrorType.networkTimeOutError,
            message: "请求超时,请稍后重试", errorMessage: ex.message);
      }

      ///用户取消
      else if (ex.type == DioErrorType.CANCEL) {
        return AppHttpException(HttpErrorType.defaultError,
            message: "用户取消操作", errorMessage: ex.message);
      }

      ///状态码错误
      else if (ex.type == DioErrorType.RESPONSE) {
        String errorString = "状态码错误";
        String responseString = ex.response?.data?.toString();
        if (responseString != null && responseString.isNotEmpty) {
          HttpResult httpResult =
              JsonConvert.fromJsonAsT<HttpResult>(json.decode(responseString));
          errorString ??= httpResult?.message;
        }

        return AppHttpException(HttpErrorType.statusError,
            message: errorString, errorMessage: ex.message);
      }
    } else if (ex is AppHttpException) {
      return ex;
    }

    return AppHttpException(HttpErrorType.defaultError, message: "请求错误,请稍后重试");
  }

  ///
  /// HttpResult get请求
  ///
  Future<HttpResult<T>> getRequest(String url,
      {Map<String, dynamic> queryParameters}) async {
    try {
      Response response = await DioSingleton.getInstance()
          .getDio()
          .get(url, queryParameters: queryParameters);
      return _getHttpResult(json.decode(response.data.toString()));
    } catch (ex) {
      throw _handleException(ex);
    }
  }

  ///
  /// HttpResult post请求
  ///
  Future<HttpResult<T>> postRequest(String url,
      {Map<String, dynamic> queryParameters, dynamic data}) async {
    try {
      Response response = await DioSingleton.getInstance()
          .getDio()
          .post(url, queryParameters: queryParameters, data: data);
      return _getHttpResult(json.decode(response.data.toString()));
    } catch (ex) {
      throw _handleException(ex);
    }
  }

  ///
  /// T get请求
  ///
  Future<T> getDirectRequest(String url,
      {Map<String, dynamic> queryParameters}) async {
    try {
      Response response = await DioSingleton.getInstance()
          .getDio()
          .get(url, queryParameters: queryParameters);
      return JsonConvert.fromJsonAsT<T>(json.decode(response.data.toString()));
    } catch (ex) {
      throw _handleException(ex);
    }
  }

  ///
  /// T post请求
  ///
  Future<T> postDirectRequest(String url,
      {Map<String, dynamic> queryParameters, dynamic data}) async {
    try {
      Response response = await DioSingleton.getInstance()
          .getDio()
          .post(url, queryParameters: queryParameters, data: data);
      return JsonConvert.fromJsonAsT<T>(json.decode(response.data.toString()));
    } catch (ex) {
      throw _handleException(ex);
    }
  }
}
